
#include "i386/mm/pagging_init.h"


uint32 pdt_address[1024];
uint32 low16m_table_address[4096];

void __init_low16m_pdt(void);
void __init_low16m_ptb(void);


// 使用物理页管理所有的内存
void init_pagging(void) {
  __init_low16m_pdt();
  __init_low16m_ptb();

  // 开启 pagging
  __asm__ __volatile__(
      "push %eax              \n"
      "lea pdt_address, %eax  \n"
      "mov %eax, %cr3         \n"
      "mov %cr0, %eax         \n"
      "or  $0x80000000, %eax  \n"
      "mov %eax, %cr0         \n"
      "pop %eax               \n"
                       );
}


// 初始化
void __init_low16m_pdt(void) {
  // 每一个 pdt 项管理 4M 的内存
  uint32* pdt_item = pdt;
  phy_addr_t phy_address = 0;
  while (phy_address < VIRTUAL_MEMSIZE << 20) {
    if (phy_address < LOWSYS_MEMSIZE << 20) {
      *pdt_item = phy_address | PAGE_PRESENT | PAGE_RWC | PAGE_SYS;
    } else {
      *pdt_item = 0;
    }

    phy_address += (1 << 22);
    pdt_item++;
  }
}

void __init_low16m_ptb(void) {
  uint32* ptb_item = low16m_ptb;
  phy_addr_t phy_address = 0;
  while (phy_address < LOWSYS_MEMSIZE << 20) {
    phy_address += (1 << 12);  // 每次增加 4K
    *ptb_item = phy_address;
    ptb_item++;
  }
}
